package com.alipay.pay.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.demo.trade.model.builder.AlipayTradeQueryRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FQueryResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.pay.config.AlipayConfig;
import com.alipay.pay.model.Order;

/**
 * 支付宝-电脑网站支付. 
 * 注意 下单页面可以加一个ajax轮询进行 订单查询避免长时间等待
 * <p>
 * 电脑网站支付 https://docs.open.alipay.com/270/105898/
 *
 * @author zhourong
 * @version 1.0
 * @since 2018/12/27
 */
@Controller
@RequestMapping("/alipay/page")
public class PayController {

	
	@Autowired
	private AlipayConfig alipayConfig;//支付宝查询接口初始化
	
	@Autowired
	private AlipayClient alipayClient;//初始化 相关配置
	
	@Autowired
	private AlipayTradeService tradeService;
	
	private final Logger log = LoggerFactory.getLogger(PayController.class);

	@GetMapping("/gotoPayPage")
	public void gotoPayPage(HttpServletResponse response,Order order) throws AlipayApiException, IOException {
		
		//下单 插入数据库
		//一系列业务判断
		//insert into order ......
		//正常业务流程会把 支付接口抽出来 
		
		// 设置请求参数
		AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
		// 同步通知地址：支付成功后页面自动跳转到传值地址中
		alipayRequest.setReturnUrl("http://zhouixi.free.idcfengye.com/alipay/page/returnUrl");
		// 异步通知地址：支付成功生成之后会post返回订单信息详情到该地址，用于商家做业务逻辑处理
		alipayRequest.setNotifyUrl("http://zhouixi.free.idcfengye.com/alipay/page/NotifyUrl");

		// 商户订单号，商户网站订单系统中唯一订单号，必填
		String out_trade_no = order.getOutTradeNo();
		// 付款金额，必填
		String total_amount = order.getTotalAmount();
		// 订单名称，必填
		String subject = order.getSubject();
		// 商品描述，可空
		String body = "用户订购商品个数：1";

		// 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。
		// 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
		String timeout_express = "5m";

		alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount
				+ "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\"," + "\"timeout_express\":\""
				+ timeout_express + "\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

		/**
		 * BizContent传值模式 alipayRequest.setBizContent("{\"out_trade_no\":\""+
		 * out_trade_no +"\"," + "\"total_amount\":\""+ total_amount +"\"," +
		 * "\"subject\":\""+ subject +"\"," + "\"qr_pay_mode\":\"4\"," +
		 * "\"timeout_express\":\"1m\"," + "\"passback_params2\":\""+ passback_params2
		 * +"\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
		 * 
		 **/
		// get请求方式，返回http链接
		// AlipayTradePagePayResponse respose = alipayClient.pageExecute(alipayRequest,
		// "get");

		// post请求方式，返回from表单
		AlipayTradePagePayResponse aliResponse = alipayClient.pageExecute(alipayRequest);
		
		// 打印请求信息
		String html = aliResponse.getBody();
		response.setContentType("text/html;charset=" + alipayConfig.getCharset());
		response.getWriter().write(html);
		response.getWriter().flush();
		response.getWriter().close();
	}

	@RequestMapping("/returnUrl")
	public String returnUrl(HttpServletRequest request, HttpServletResponse response)
			throws UnsupportedEncodingException, AlipayApiException {
		response.setContentType("text/html;charset=" + "utf-8");
		boolean verifyResult = this.checkParam(request);
		if (verifyResult) {
			// 验证成功
			//添加自己的业务。。。进行业务核对
			// 商户订单号
			String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
			// 支付宝交易号
			String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
			
			// (必填) 商户订单号，通过此商户订单号查询当面付的交易状态
	        AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
	        		.setOutTradeNo(out_trade_no);
			AlipayF2FQueryResult result = tradeService.queryTradeResult(builder);
			System.out.println(result.getTradeStatus());
			return "success";
		} else {
			return "fail";
		}
	}

	@RequestMapping("/notifyUrl")
	public String NotifyUrl(HttpServletRequest request, HttpServletResponse response)
			throws UnsupportedEncodingException, AlipayApiException {
		response.setContentType("text/html;charset=" + "utf-8");

		boolean verifyResult = this.checkParam(request);
		if (verifyResult) {
			// 验证成功
			//添加自己的业务。。。进行业务核对
			// 商户订单号
			String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
			// 支付宝交易号
			String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
			
			// (必填) 商户订单号，通过此商户订单号查询当面付的交易状态
	        AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
	        		.setOutTradeNo(out_trade_no);
			AlipayF2FQueryResult result = tradeService.queryTradeResult(builder);
			System.out.println(result.getTradeStatus());
			return "success";
		} else {
			return "fail";
		}
	}

	/**
	 * 校验签名
	 * 
	 * @param request
	 * @return
	 */
	private boolean checkParam(HttpServletRequest request) {
		// https://docs.open.alipay.com/54/106370  官方文档
		// 获取支付宝POST过来反馈信息
		Map<String, String> params = new HashMap<>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			params.put(name, valueStr);
		}

		try {
			boolean verifyResult = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(),
					alipayConfig.getCharset(), alipayConfig.getSignType());
			return verifyResult;
		} catch (AlipayApiException e) {
			log.debug("verify sigin error, exception is:{}", e);
			return false;
		}
	}
}
